// Land.h: interface for the Land class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(LAND_H)
#define LAND_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/* PLIB includes */
#include <plib/ul.h>
#include <plib/sg.h>
#include <plib/ssg.h>

/* Project class includes */
#include "../../DEFINES.h"

#define FILE_ROW_STRING_LENGTH 1024

#define LAND_FILENAME_STRING_LENGTH 80

#define LAND_FILE_TYPE_DEM	0
#define LAND_FILE_TYPE_XYZ	1

/* number of squares (Y x Y) of each leaf */
#define LAND_TRIANGLE_GRID_SIZE		2

/* textures lambda multiplication factor */
#define LAND_TEXTURES_LAMBDA_MULT_FACTOR 4.0f

#define LAND_TEXTURES_PATH "./Scenegraph/Land/Textures/bumpnoise.rgb"
#define STONES_TEXTURES_PATH "./Scenegraph/Land/Textures/bumpnoise.rgb"
#define BURNT_TEXTURES_PATH "./Scenegraph/Land/Textures/stones.rgb"
#define SNOW_TEXTURES_PATH "./Scenegraph/Land/Textures/snow1.bmp"

// States for textures
#define LAND_STONE_STATE		0

// Distance from viewer for change detail level
#define LAND_RANGE_NEAR_VIEW	0.0f
#define LAND_RANGE_MIDDLE_VIEW	500000.0f
#define LAND_RANGE_FAR_VIEW		1000000.0f
#define LAND_RANGE_LIMIT_VIEW	1500000.0f

#define THIN_FACTOR_NEAR   1
#define THIN_FACTOR_MIDDLE 1
#define THIN_FACTOR_FAR    1

#define Z_FACTOR_NEAR     0.0f
#define Z_FACTOR_MIDDLE -30.0f
#define Z_FACTOR_FAR    -60.0f

// Height color map
static sgVec4 heightColors[7] = { 
							0.1f, 0.7f, 0.0f, 1.0f,      // dark green
							0.2f, 0.7f, 0.1f, 1.0f,		 // green
                            0.3f, 0.7f, 0.2f, 1.0f,      // olive brown
							0.8f, 0.8f, 0.9f, 1.0f,      // brown
							0.84f, 0.94f, 0.96f, 1.0f,      // gray
							0.3f, 0.3f, 0.4f, 1.0f,		 // stone
							0.84f, 0.94f, 0.96f, 1.0f    // ice
							};
// Color zones limits
#define LAND_LOW_PLAINS_COLOR		250.0f
#define LAND_HIGH_PLAINS_COLOR		500.0f
#define LAND_LOW_HILLS_COLOR		800.0f
#define LAND_HIGH_HILLS_COLOR		1200.0f
#define LAND_MOUNTAINS_COLOR		2500.0f
#define LAND_SNOWY_MOUNTAINS_COLOUR	3000.0f

#define LAND_MIN_INCLINATION_FOR_ROCKS 0.8


class Land  
{
public:
	//loads in memory the height datas, from files of type 'type'
	//(see DEFINES.h)
	//WARNING! Here I just load datas in memory... to create the
	//Scenegraph's node, use buildTerrain()!
	Land(char filename[]);
	virtual ~Land();

	//creates Land's scenegraph's tree
	void buildTerrain();

	//to get the node
	ssgTransform* getNode();

	// some getters (map start roma 1940 coords)
	float getStartXCoord();
	float getStartYCoord();

	// map is always centered in the origin... so these are the values
	// of translation along x and y axes
	float getStartRecenteringX();
	float getStartRecenteringY();

	
	float getGridStep();

	// set the texture for the given leaf
	void setState(ssgLeaf* leaf,int type);

	// number of leaves 
	int getLeavesNumber();

	// To test the number of leaves drawn
	void resetNumberOfLeavesDrawn();
	int getNumberOfLeavesDrawn();
	int getMeanNumberOfLeavesDrawn();
	int getMeanNumberOfFarLeavesDrawn();
	int getMeanNumberOfMedLeavesDrawn();
	int getMeanNumberOfNearLeavesDrawn();

private:
	// methods used to create the sub-sectors and the leaves of the map
	void createTile(int x, int y, sgVec3 tilepos);
	ssgBranch* createTilePortion(int x, int y, int ntris, sgFloat z_off, sgVec3 tilepos);

	// Data map 
	char filename[1024];		//DEM (or XYZ) file name
	sgFloat* landMap;								//height data matrix
	int mapRows;									//matrix row number
	int mapCols;									//matrix column number
	int x_start_coord;								//map x (c) start East coord
	int y_start_coord;								//map y (r) start North coord
	int gridStep;									//grid step (in meters)
	int gridThinFactor;								//grid thin factor
	sgFloat max;									//terrain max height
	sgFloat min;									//terrain min height 

	int triangle_grid_size;							// number of squares per side in each leaf
	int tile_size;									// leaves side dimension 

	int exceeding_r;
	int exceeding_c;

	int tile_grid_number_x ;						// number of leaves along x
	int tile_grid_number_y ;						// number of leaves along y

	int online_terrain_range_x ;					// center point (x) of the terrain (if it's bottom left corner lies over the origin)
	int online_terrain_range_y ;					// center point (y) of the terrain (if it's bottom left corner lies over the origin)

	sgFloat lambda;									// lambda factor for textures

	// Tile sector's possible states 
	ssgSimpleState *grassState;						// tile with grass
	ssgSimpleState *grassNoTextureState;			// green tile, no texture
	ssgSimpleState *stoneState;						// tile with stones
	ssgSimpleState *stoneNoTextureState;			// gray tile, no stone 
	ssgSimpleState *burntState;						// burnt grass

	// land transform node
	ssgTransform *landTransform;
	ssgTransform *terrainRecenteringTransform;

	// tile grid nodes matrix
	ssgTransform **tileGrid;

	// total leaves number
	int totalLeavesNumber;
	int leavesBuilt;
	void printStatistics();
	void printTerrainData();
};


// Class static members
static int noi;
static int mean;
static int meanFar,totFar;
static int meanMed,totMed;
static int meanNear,totNear;
static int min;
static int max;
static int numberOfFarLeavesDrawn;
static int numberOfMedLeavesDrawn;
static int numberOfNearLeavesDrawn;
static int leafFarCallback(ssgEntity *e);

#endif // !defined(LAND_H)
